﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace DL
{
    [Serializable]
    public class BlackboardEntryData : ISerializationCallbackReceiver
    {
        public string keyName;
        public AnyValue.ValueType valueTypel;
        public AnyValue value;

        /// <summary>
        /// 快速填充黑板数据行为
        /// </summary>
        private static
            Dictionary<AnyValue.ValueType, Action<GameBlackboard, GameBlackboardKey, AnyValue>>
            m_SetValueDispatchTable = new()
            {
                {AnyValue.ValueType.Int, (gameBlackboard,key,anyValue) => {gameBlackboard.SetValue<int>(key,anyValue); } },
                {AnyValue.ValueType.Bool, (gameBlackboard,key,anyValue) => {gameBlackboard.SetValue<bool>(key,anyValue); } },
                {AnyValue.ValueType.Float, (gameBlackboard,key,anyValue) => {gameBlackboard.SetValue<float>(key,anyValue); } },
                {AnyValue.ValueType.String, (gameBlackboard,key,anyValue) => {gameBlackboard.SetValue<string>(key,anyValue); } },
                {AnyValue.ValueType.Vector3, (gameBlackboard,key,anyValue) => {gameBlackboard.SetValue<Vector3>(key,anyValue); } },
                {AnyValue.ValueType.Vector2, (gameBlackboard,key,anyValue) => {gameBlackboard.SetValue<Vector2>(key,anyValue); } },
            };

        public void SetValueOnGameBlackboard(GameBlackboard gameBlackboard)
        {
            var key = gameBlackboard.GetOrRegistry(keyName);
            m_SetValueDispatchTable[value.type](gameBlackboard, key, value);
        }

        public void OnBeforeSerialize()
        {
        }

        public void OnAfterDeserialize() => value.type = valueTypel;
    }

    [Serializable]
    public struct AnyValue
    {
        public enum ValueType
        {
            Int,
            Float,
            Bool,
            String,
            Vector3,
            Vector2,
        }

        public ValueType type;
        
        //存储空间
        public int intValue;
        public float floatValue;
        public bool boolValue;
        public string stringValue;
        public Vector3 vector3Value;
        public Vector2 vector2Value;
        public object classValue;


        //内联转换  
        public static implicit operator int(AnyValue value) => value.ConvertValue<int>();
        public static implicit operator float(AnyValue value) => value.ConvertValue<float>();
        public static implicit operator bool(AnyValue value) => value.ConvertValue<bool>();
        public static implicit operator string(AnyValue value) => value.ConvertValue<string>();
        public static implicit operator Vector3(AnyValue value) => value.ConvertValue<Vector3>();
        public static implicit operator Vector2(AnyValue value) => value.ConvertValue<Vector2>();
        
        T ConvertValue<T>()
        {
            return type switch
            {
                ValueType.Int => AsInt<T>(intValue),
                ValueType.Float => AsFloat<T>(floatValue),
                ValueType.Bool => AsBool<T>(boolValue),
                ValueType.String => (T)(object)stringValue,
                ValueType.Vector3 => (T)(object)vector3Value,
                ValueType.Vector2 => (T)(object)vector2Value,
                _ => throw new NotSupportedException($"Not supported value type: {typeof(T)}"),
            };
        }

        //转换方法
        T AsBool<T>(bool value) => typeof(T) == typeof(bool) && value is T correctType ? correctType : default;   
        T AsInt<T>(int value) => typeof(T) == typeof(bool) && value is T correctType ? correctType : default;   
        T AsFloat<T>(float value) => typeof(T) == typeof(bool) && value is T correctType ? correctType : default;   


    }
}